<?php

namespace App\Constants;

use Attribute;
use ReflectionClass;
use ReflectionAttribute;
use InvalidArgumentException;

/**
 * 基础Enum抽象类
 * 使用Typed Properties和Union Types定义属性类型
 * 使用Attributes标注Enum的元数据
 */
abstract class AbstractEnum
{
    /**
     * 枚举值
     */
    protected string|int $value;

    /**
     * 标签（显示名称）
     */
    protected string $label;

    /**
     * 描述信息
     */
    protected ?string $description;

    /**
     * 颜色标识
     */
    protected ?string $color;

    /**
     * 图标标识
     */
    protected ?string $icon;

    /**
     * 排序权重
     */
    protected int $sort;

    /**
     * 是否启用
     */
    protected bool $enabled;

    /**
     * 构造函数
     */
    protected function __construct(
        string|int $value,
        string $label,
        ?string $description = null,
        ?string $color = null,
        ?string $icon = null,
        int $sort = 0,
        bool $enabled = true
    ) {
        $this->value = $value;
        $this->label = $label;
        $this->description = $description;
        $this->color = $color;
        $this->icon = $icon;
        $this->sort = $sort;
        $this->enabled = $enabled;
    }

    /**
     * 获取枚举值
     */
    public function getValue(): string|int
    {
        return $this->value;
    }

    /**
     * 获取标签
     */
    public function getLabel(): string
    {
        return $this->label;
    }

    /**
     * 获取描述
     */
    public function getDescription(): ?string
    {
        return $this->description;
    }

    /**
     * 获取颜色
     */
    public function getColor(): ?string
    {
        return $this->color;
    }

    /**
     * 获取图标
     */
    public function getIcon(): ?string
    {
        return $this->icon;
    }

    /**
     * 获取排序权重
     */
    public function getSort(): int
    {
        return $this->sort;
    }

    /**
     * 是否启用
     */
    public function isEnabled(): bool
    {
        return $this->enabled;
    }

    /**
     * 获取所有枚举值
     */
    public static function getAll(): array
    {
        $reflection = new ReflectionClass(static::class);
        $constants = $reflection->getConstants();
        $instances = [];

        foreach ($constants as $name => $value) {
            if (is_object($value) && $value instanceof static) {
                $instances[] = $value;
            }
        }

        // 按排序权重排序
        usort($instances, fn($a, $b) => $a->sort <=> $b->sort);

        return $instances;
    }

    /**
     * 获取所有启用的枚举值
     */
    public static function getEnabled(): array
    {
        return array_filter(static::getAll(), fn($item) => $item->enabled);
    }

    /**
     * 根据值获取枚举实例
     */
    public static function fromValue(string|int $value): ?static
    {
        foreach (static::getAll() as $instance) {
            if ($instance->value === $value) {
                return $instance;
            }
        }

        return null;
    }

    /**
     * 根据标签获取枚举实例
     */
    public static function fromLabel(string $label): ?static
    {
        foreach (static::getAll() as $instance) {
            if ($instance->label === $label) {
                return $instance;
            }
        }

        return null;
    }

    /**
     * 验证值是否有效
     */
    public static function isValid(string|int $value): bool
    {
        return static::fromValue($value) !== null;
    }

    /**
     * 获取枚举值数组（用于表单选择等）
     */
    public static function toArray(): array
    {
        $result = [];
        foreach (static::getEnabled() as $instance) {
            $result[$instance->value] = $instance->label;
        }
        return $result;
    }

    /**
     * 获取枚举值详细数组
     */
    public static function toDetailArray(): array
    {
        $result = [];
        foreach (static::getEnabled() as $instance) {
            $result[] = [
                'value' => $instance->value,
                'label' => $instance->label,
                'description' => $instance->description,
                'color' => $instance->color,
                'icon' => $instance->icon,
                'sort' => $instance->sort,
            ];
        }
        return $result;
    }

    /**
     * 字符串表示
     */
    public function __toString(): string
    {
        return (string) $this->value;
    }

    /**
     * 比较方法
     */
    public function equals(self $other): bool
    {
        return $this->value === $other->value;
    }

    /**
     * 获取元数据属性
     */
    protected static function getMetadata(string $constantName): array
    {
        $reflection = new ReflectionClass(static::class);
        $constant = $reflection->getReflectionConstant($constantName);
        
        if (!$constant) {
            return [];
        }

        $attributes = $constant->getAttributes();
        $metadata = [];

        foreach ($attributes as $attribute) {
            $metadata[] = $attribute->newInstance();
        }

        return $metadata;
    }
}
